﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using DoNet.FrameWork.Repository.Specification;
using Authority.Entity;
using Authority.Services;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;

namespace MvcApp.Models
{
    public class MenuData
    {
        public Guid menuid { get; set; }
        public string icon { get; set; }
        public string menuname { get; set; }
        public string url { get; set; }
        public List<MenuData> menus { get; set; }        

        private readonly IModulesService _modulesService;
        private readonly List<string> _modulesCodes;

        public MenuData() { }

        public MenuData(IModulesService modulesService, List<string> modulesCodes)
        {
            _modulesService = modulesService;
            _modulesCodes = modulesCodes;
        }

        public string GetJson()
        {
            string jsonString;
            MenuData menuData = new MenuData();
            menuData.menus = this.Recursion(new Guid("00000000-0000-0000-0000-000000000000"));
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MenuData));
            MemoryStream ms = new MemoryStream();
            ser.WriteObject(ms, menuData);
            jsonString = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            return jsonString;
        }

        private List<MenuData> Recursion(Guid id)
        {
            List<MenuData> mds = new List<MenuData>();
            ISpecification<Modules> condition = new DirectSpecification<Modules>(m => m.IsDeleted == false);
            ISpecification<Modules> recursionCondition = new DirectSpecification<Modules>(m => m.ParentId == id);
            ISpecification<Modules> menuCondition = new DirectSpecification<Modules>(m => m.IsMenu == true);
            ISpecification<Modules> moduleConditon = new DirectSpecification<Modules>(m => _modulesCodes.Contains(m.Code));
            condition = new AndSpecification<Modules>(condition, recursionCondition);
            condition = new AndSpecification<Modules>(condition, menuCondition);
            condition = new AndSpecification<Modules>(condition, moduleConditon);
            Expression<Func<Modules, string>> orderByExpression = m => m.Code;
            List<Modules> modules = _modulesService.GetList<string>(condition, orderByExpression, false);
            if (modules.Count > 0)
            {
                foreach (Modules m in modules)
                {
                    MenuData md = new MenuData();
                    md.menuid = m.Id;
                    md.menuname = m.Name;
                    md.icon = m.Icon;
                    md.url = m.NavigateUrl;
                    md.menus = this.Recursion(m.Id);
                    mds.Add(md);
                }
            }
            return mds;
        }

    }
}